#include <Windows.h>
#include <CommCtrl.h>
#include "../Application/Application.h"
#include "../Layout/HorizontalLayout.h"
#include "../Layout/VerticalLayout.h"
#include "Slider.h" 

namespace GUI
{
	namespace Win32
	{

		Slider::Slider(int _iMin, int _iMax, int _iDefaultValue) : m_iMin(_iMin), m_iMax(_iMax), m_iDefaultValue(_iDefaultValue), m_iWidth(-1), m_iHeight(-1)
		{
			m_iId = Application::GetId();
			Application::RegisterWidget(this);
		}

		Slider::Slider(int _iMin, int _iMax, int _iDefaultValue, int _iWidth, int _iHeight) : m_iMin(_iMin), m_iDefaultValue(_iDefaultValue), m_iMax(_iMax), m_iWidth(_iWidth), m_iHeight(_iHeight)
		{
			m_iId = Application::GetId();
			Application::RegisterWidget(this);
		}

		Slider::~Slider()
		{
			Application::UnregisterWidget(this);
		}

		void Slider::Create(HWND _hWindow, HINSTANCE _hInstance)
		{
			m_iValue = m_iDefaultValue;
			m_hSlider = CreateWindowEx(NULL, TRACKBAR_CLASS, NULL, WS_CHILD | WS_VISIBLE | TBS_HORZ | TBS_FIXEDLENGTH, GetX(), GetY(), GetWidth(), GetHeight(), _hWindow, (HMENU)m_iId, _hInstance, NULL);
			SendMessage(m_hSlider, TBM_SETRANGE, TRUE, MAKELONG(m_iMin, m_iMax));
			SendMessage(m_hSlider, TBM_SETPOS, TRUE, m_iDefaultValue);
		}

		Core::GUI::WidgetType Slider::GetType() const
		{
			return Core::GUI::WidgetType::Slider;
		}

		int Slider::GetId() const
		{
			return m_iId;
		}

		void Slider::Accept(Core::GUI::IVerticalLayout * _pVerticalLayout)
		{
			((VerticalLayout*)_pVerticalLayout)->Visit(this);
		}

		void Slider::Accept(Core::GUI::IHorizontalLayout * _pHorizontalLayout)
		{
			((HorizontalLayout*)_pHorizontalLayout)->Visit(this);
		}
		
		int Slider::GetWidth() const
		{
			return m_iWidth;
		}

		int Slider::GetHeight() const
		{
			return m_iHeight;
		}

		int Slider::GetX() const
		{
			return m_iX;
		}

		int Slider::GetY() const
		{
			return m_iY;
		}

		void Slider::Resize(int _iWidth, int _iHeight)
		{
			m_iWidth = _iWidth;
			m_iHeight = _iHeight;
			MoveWindow(m_hSlider, m_iX, m_iY, _iWidth, _iHeight, true);
		}

		void Slider::Move(int _x, int _y)
		{
			m_iX = _x;
			m_iY = _y;
			MoveWindow(m_hSlider, _x, _y, m_iWidth, m_iHeight, true);
		}

		void Slider::OnValueChanged(VoidFunctionInt _function)
		{
			m_fctOnValueChanged = _function;
		}

		void Slider::SetValue(int _iValue)
		{
			m_iValue = _iValue;
			if (m_fctOnValueChanged)
			{
				m_fctOnValueChanged(m_iValue);
			}
		}

		int Slider::GetValue() const
		{
			return m_iValue;
		}

		void Slider::DecValue()
		{
			if (m_iValue > m_iMin)
			{
				m_fctOnValueChanged(--m_iValue);
			}
		}

		void Slider::IncValue()
		{
			if (m_iValue < m_iMax)
			{
				m_fctOnValueChanged(++m_iValue);
			}
		}
	}
}